package com.xinxin.base.handler;

import com.xinxin.base.entity.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolationException;

@Slf4j
public class ValidExceptionHandler {

    /**
     * 第一步，参数解析 RequestParam
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public ApiResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.debug("参数解析异常", e);
        return ApiResult.code(HttpStatus.BAD_REQUEST).msg(e.getMessage());
    }

    /**
     * 第二步，参数转换
     */
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    public ApiResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
        log.debug("参数转换异常", e);
        return ApiResult.code(HttpStatus.BAD_REQUEST).msg(e.getMessage());
    }

    @ExceptionHandler(value = HttpMessageConversionException.class)
    public ApiResult handleHttpMessageConversionException(HttpMessageConversionException e) {
        log.error("参数转换异常", e);
        return ApiResult.code(HttpStatus.BAD_REQUEST).msg(e.getMessage());
    }

    /**
     * 第三步，参数校验
     */
    // Json 传参
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ApiResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.debug("非法参数", e);
        return ApiResult.code(HttpStatus.BAD_REQUEST).msg(e.getMessage());
    }

    // 实体对象传参
    @ExceptionHandler(value = BindException.class)
    public ApiResult handleBindException(BindException e) {
        log.debug("非法参数", e);
        return ApiResult.code(HttpStatus.BAD_REQUEST).msg(e.getMessage());
    }

    /**
     * 进入Controller才校验，Controller层切面需放行此异常
     */
    // 普通传参
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ApiResult handleConstraintViolationException(ConstraintViolationException e) {
        log.debug("非法参数", e);
        return ApiResult.code(HttpStatus.BAD_REQUEST).msg(e.getMessage());
    }
}
